import java.io.*;

/*
<程序> →<变量说明部分>;<语句部分>
<变量说明部分> → <变量说明><标识符列表>
<变量说明> → int //<变量说明> → string

<标识符列表> → <标识符><标识符列表prime> //<标识符列表> → <标识符列表>,<标识符>|<标识符>
<标识符列表prime> → ,<标识符><标识符列表prime>|ε //<标识符> → <字母>|<标识符><字母>|<标识符><数字>

<语句部分> → <语句>;<语句部分prime> //<语句部分> → <语句部分><语句>;|<语句>;
<语句部分prime> → <语句>;<语句部分prime>|ε //

<语句> → <赋值语句>|<条件语句>|<循环语句>
<赋值语句> → <标识符>=<表达式>
<条件语句> → if （<条件>） then <嵌套语句>; else <嵌套语句> //<条件语句> → if （<条件>）<嵌套语句> else <嵌套语句>
<循环语句> → while （<条件>） do <嵌套语句> // <循环语句> → do <嵌套语句> while （<条件>）

<表达式> → <项><表达式prime> //<表达式> → <项>|<表达式><连接运算符><项>
<表达式prime> → <加法运算符><项><表达式prime>|ε //

<项> → <因子><项prime> //<项> → <因子>|<项><重复运算符><数字>
<项prime> → <乘法运算符><因子><项prime>|ε //

<因子> → <标识符>|<常量>|(<表达式>)
<常量> → <无符号整数> // <字符串> → “<字母序列>”
<无符号整数> → <数字序列> // <字母序列> → <字母序列><字母>|ε

<数字序列> → <数字><数字序列prime> //
<数字序列prime> → <数字><数字序列prime>|ε //

<加法运算符> → + //<连接运算符> → +
<乘法运算符> → * //<重复运算符> → *
<关系运算符> → <|>|!= |>=|<= |== // <关系运算符> → <|>|<> |>=|<= |==
<条件> → <表达式><关系运算符><表达式>
<复合语句> → begin <语句部分> end //<复合语句> → start <语句部分> end
<嵌套语句> → <语句>|<复合语句>
<字母> → a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z
<数字> → 0|1|2|3|4|5|6|7|8|9
 */
public class main {
    public static void main(String[] args) throws IOException {
        String fileName = "in.txt";
        FileReader fileReader = new FileReader(fileName);
        char[] inputProgram = new char[10000];
        fileReader.read(inputProgram);
        for(int i = 0; inputProgram[i]!= '\u0000' ; i++){
            if(inputProgram[i+1] == '\u0000'){
                inputProgram[i+1] = '#';
                break;
            }
        }
        File outfile = new File("out.txt");
        if(!outfile.exists()){
            outfile.createNewFile();
        }
        File debugfile = new File("debug.txt");
        if(!debugfile.exists()){
            debugfile.createNewFile();
        }
        //  初始化
        FileWriter fileWriter1 = new FileWriter(outfile.getName(),true);
        FileWriter fileWriter2 = new FileWriter(debugfile.getName(),true);

        Methods method = new Methods(inputProgram, 0);
        method.identifierTable.clear();
        method.codeTable.clear();
        method.tempVarTable.clear();
        // 识别第一个单词
        method.word = method.nextInput(inputProgram);
        System.out.println("【词】:识别第一个单词为" + "(" + method.word.type + "," + method.word.value + ")");
        System.out.println("【语】<程序>→<变量说明部分>;<语句部分>#");
        fileWriter2.write("【语】<程序>→<变量说明部分>;<语句部分>#\n");

        //  推导
        method.ParseProgram();

        fileWriter2.write(String.valueOf(method.output));
        //  打印标识符列表
        System.out.println(method.identifierTable.dump());
        //  写入标识符列表
        fileWriter2.write(method.identifierTable.dump());

        System.out.println("const table:");
        fileWriter2.write("const table:");
        for(String value: method.ConstTable.keySet()) {
            // 输出每一个value
            System.out.print(value + "; ");
            fileWriter2.write(value + "; ");
        }
        System.out.println("\n");
        fileWriter2.write("\n");

        //  打印临时变量列表
        System.out.println(method.tempVarTable.dump());
        //  写入临时变量列表
        fileWriter2.write(method.tempVarTable.dump());
        //  打印四元式列表
        System.out.println(method.codeTable.dump());
        //  写入四元式列表
        fileWriter1.write(method.codeTable.dump());
        fileWriter2.close();
        fileWriter1.close();
    }
}


